package com.bestcem.xm.user.util.business;

import com.bestcem.xm.common.core.sequence.dao.SequenceDao;
import com.bestcem.xm.common.core.sequence.entity.SequenceDO;
import com.bestcem.xm.common.core.sequence.entity.SequenceEntity;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.user.constant.UserCacheKeyConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 组织层级全局版本号工具类
 *
 * @author qiongyu.cui <qiongyu.cui@idiaoyan.com>
 * @version v1.0
 * @date 2022/2/11 16:26
 */
@Component
@Slf4j
public class GroupSequenceUtil {

    @Autowired
    private SequenceDao sequenceDao;

    @Autowired
    private RedisService redisService;

    private static final int INCREMENT_STEP = 1000;

    /**
     * 根据租户id获取当前租户下的组织层级的版本号信息
     *
     * @param orgId 租户id
     * @return int 版本号信息
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/11 16:45
     */
    public int getVersion(String orgId) {
        String versionKey = String.format(UserCacheKeyConstant.USER_GROUP_LEVEL_VERSION, orgId);
        // 从redis中获取
        Boolean bool = redisService.hasKey(versionKey);
        if (null != bool && bool) {
            return Integer.parseInt(redisService.get(versionKey).toString());
        }

        // 否则直接从mysql中获取
        return getVersionAndInitByMysql(versionKey);
    }

    /**
     * 根据租户id自增当前版本号
     *
     * @param orgId 租户id
     * @return int 自增后的版本号
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/11 16:46
     */
    public int incrementVersion(String orgId) {
        String versionKey = String.format(UserCacheKeyConstant.USER_GROUP_LEVEL_VERSION, orgId);
        // 判断redis是否已存在
        Boolean bool = redisService.hasKey(versionKey);
        Integer version;
        if (null != bool && bool) {
            version = Integer.valueOf(redisService.get(versionKey).toString());
        } else {
            // 不存在则从mysql中查询或者初始化
            return getVersionAndInitByMysql(versionKey);
        }

        if (version % INCREMENT_STEP == 0) {
            // 说明上一次从mysql中取的结果已经被用完，需要重新在取一次
            sequenceDao.findOneAndUpdateByCodeAndSeqInc(versionKey, INCREMENT_STEP);
        }
        // redis继续自增
        return redisService.incr(versionKey, 1).intValue();
    }

    /**
     * 从mysql中获取指定code对应的seq值
     * 如果没有则初始化一条seq从1开始的数据，同步塞入到redis缓存
     *
     * @param versionKey code
     * @return int
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/11 17:30
     */
    public int getVersionAndInitByMysql(String versionKey) {
        int version = 1;
        SequenceDO sequenceInfo = sequenceDao.findOneByCode(versionKey);
        if (null == sequenceInfo) {
            // 创建一条数据seq数据
            Date now = new Date();
            SequenceEntity entity = new SequenceEntity();
            entity.setSeq(INCREMENT_STEP);
            entity.setUpdateTime(now);
            entity.setCreateTime(now);
            entity.setIncrStep(INCREMENT_STEP);
            entity.setCode(versionKey);
            SequenceDO insertResult = sequenceDao.findOneAndUpdateByCode(entity);
            if (null != insertResult) {
                version = insertResult.getSeq();
            }
        } else {
            version = sequenceInfo.getSeq();
        }
        // 同步插入到redis中
        redisService.setIfAbsent(versionKey, version);
        return version;
    }

}
